# _*_ coding: utf-8 _*_
"""
@ 时间    ：2024/10/24 9:31
@ 作者    ：旺财
@ 文件    ：02 GBDT算法.py
@ 说明    ： 产品定价模型
"""
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.ensemble import GradientBoostingRegressor
from sklearn.metrics import mean_squared_error, mean_absolute_error, r2_score
from sklearn.model_selection import GridSearchCV

# 1.数据读取与处理
df = pd.read_excel('产品定价模型.xlsx')
print('数据展示:原始数据')
print(df.head())
print('数据处理:文本数值化')


# 对类别和纸张进行数值映射
df['类别'] = df['类别'].map({'技术类': 1, '教辅类': 2, '办公类': 3})
df['纸张'] = df['纸张'].map({'双胶纸': 1, '铜版纸': 2, '书写纸': 3})
print(df.head())

# 2.提取特征变量与目标变量
x = df.drop(columns='价格')
y = df['价格']

# 3.划分训练集与测试集
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2, random_state=123)

# 4.建立模型
# 定义参数网格
param_grid = {
    'learning_rate': [0.05, 0.1, 0.2],
    'n_estimators': [50, 100, 150],
    'max_depth': [3, 5, 7]
}

# 使用网格搜索进行超参数调整
model = GradientBoostingRegressor(random_state=123)
grid_search = GridSearchCV(model, param_grid, cv=5, scoring='neg_mean_squared_error')
grid_search.fit(x_train, y_train)

# 获取最佳模型
best_model = grid_search.best_estimator_
print(f'最佳模型:{best_model}')
best_params = grid_search.best_params_
print(f'最佳参数:{best_params}')
print()

# 5.模型评估
# 预测结果
df_score = pd.DataFrame()
df_score['预测结果'] = list(best_model.predict(x_test))
df_score['实际结果'] = list(y_test)
print(df_score.head())
print()

# 计算多种评估指标
mse = mean_squared_error(y_test, df_score['预测结果'])
mae = mean_absolute_error(y_test, df_score['预测结果'])
r2 = r2_score(y_test, df_score['预测结果'])

print(f'均方误差（MSE）为：{mse}')
print(f'平均绝对误差（MAE）为：{mae}')
print(f'模型精准度（R²）为：{round(r2*100, 2)}%')
print()

# 查看重要特征
df_importance = pd.DataFrame()
df_importance['特征名称'] = x.columns
df_importance['特征重要性'] = best_model.feature_importances_
print(df_importance)